package com.uinnova.product.eam.feign.config;

import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;

/**
 * 做请求头转发
 * 
 * @author zhaoyujie
 *
 */
// @Component
public class EamFeignConfig implements RequestInterceptor {

	private static Logger log = LoggerFactory.getLogger(EamFeignConfig.class);

	/**
	 * 不转发header
	 */
	private Set<String> noForwardHeaderNames = new HashSet<>();
	{
		noForwardHeaderNames.add("content-type");
		noForwardHeaderNames.add("content-length");
		noForwardHeaderNames.add("connection");
		noForwardHeaderNames.add("accept");
		log.info("base client实例成功，为避免问题，以下请求头不转发至feign mvc【{}】", noForwardHeaderNames);
	}

	/**
	 * 重写文件头方法
	 */
	@Override
	public void apply(RequestTemplate template) {
		ServletRequestAttributes attrs = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		if (attrs != null) {
			// 转发所有headers
			forwardHeader(attrs, template);
			// 塞feign标识
			String requestId = attrs.getRequest().getHeader("requestId");
            if (requestId != null && !"".equals(requestId.trim())) {
                template.header("sourceRequestId", requestId);
            }
			template.header("feignRequestId", UUID.randomUUID().toString());
		} else {
			log.error("获取http上下文，可能发生线程切换或未传递上下文或为共享子线程信息；无法传递请求头");
		}
	}

	/**
	 * 转发头
	 * 
	 * @param attrs
	 * @param template
	 */
	private void forwardHeader(ServletRequestAttributes attrs, RequestTemplate template) {
		Enumeration<String> headerNames = attrs.getRequest().getHeaderNames();
		while (headerNames.hasMoreElements()) {
			String headerName = headerNames.nextElement();
			String headerVal = attrs.getRequest().getHeader(headerName);
			if (!noForwardHeaderNames.contains(headerName.toLowerCase())) {
				template.header(headerName, headerVal);
			}
		}
	}

}
